using System;
using System.Collections.Generic;
using System.Runtime.Serialization;

using BLToolkit.Mapping;

using TrueCode.Core.Aspects;
using TrueCode.Core.EditableEntity;
using TrueCode.Core.Validation;

namespace EMan.Common.EnterpriseStructure
{
  /// <remarks> <see cref="DataContract.IsReference"/> is set to true in order to be able to serialize cyclic 
  /// references - parent references its children and vise versa</remarks>
  [DataContract( IsReference = true )]
  public class Department : ReferenceEntity< Department >
  {
    private static int _idgen = -1;

    [ DataMember ]
    private readonly List< Employee > _employees = new List< Employee >();

    public Department( string name, string description = null ) : this( Guid.NewGuid(), _idgen--, name, description, 0 ){}

    private Department( Guid key, int id, string name, string description, int revision )
    {
      Key = key;
      Id = id;

      Title = name;
      Description = description;
      Revision = revision;
    }

    [DataMember]
    [Trimmable]
    [Validate.NotEmpty, Validate.MaxLength(50)]
    [Editable(EditableMode.All)]
    public string Title { get; set; }

    [DataMember]
    [NullValue( null )]
    [Validate.MaxLength(500)]
    [Editable(EditableMode.All)]
    public string Description { get; set; }

    public IEnumerable< Employee > Employees
    {
      get { return _employees; }
    }

    public void Add( Employee employee )
    {
      if( employee.Department != this ) throw new ArgumentException( "Employees' department is not this", "employee" );

      _employees.Add( employee );
    }

    public Department Copy()
    {
      return new Department( Key, Id, Title, Description, Revision );
    }

    [Obsolete( "This constructor is for BLT and testing only"), UsedImplicitly]
    public Department() : this( Guid.NewGuid(), int.MinValue, string.Empty, string.Empty, -1 ){}
  }
}